import { useEffect, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import { message, Skeleton, Form, Radio, Checkbox, Select, Rate, Input, Button } from "antd";
import TextArea from "antd/es/input/TextArea";
import type { Rule } from "antd/es/form";
import shortId from "shortid";
import type { questionType, answerType, surveyAnswerType, QuestionControlType, optionType, questionListType } from "@/types/index";
import { answerSave, answerSelected } from "@/computed/answer";
import { fillValidateMap } from "@/utils/validate";
import { surveyStore } from "@/stores/survey";
import { getQueryParams, getTime, timeDiff } from "@/utils";
import { generateColumn } from "@/utils/calculation";
import { typeEnum, validateEnum } from "@/assets/common/enums";
import MatrixItrem from "@/components/MatrixItem/MatrixItem";
import SliderItem from "@/components/SliderItem/SliderItem";
import { QuestionContent } from "./stye";

const { RADIO, CHECKBOX, DROP, SCORE, FILL, PAGING, PARAGRAPH, SLIDER, MATRIX_RADIO, MATRIX_CHECKBOX, MATRIX_SLIDER } = typeEnum;

// 选项筛选
const filterAnswer = (hideNum: number[] | undefined, option: optionType[]) => {
  if (hideNum?.length) {
    return option.filter(item => !hideNum.includes(item.id));
  } else {
    return option;
  }
};

// 验证规则
const rulesValidate = (item: questionType) => {
  return item.must
    ? [
        {
          required: true,
          validator: (_rule: Rule, value: string | number | number[]) => {
            // 对value进行初步的类型和空值检查
            if ((!value && value !== 0) || (Array.isArray(value) && value.length === 0)) {
              return Promise.reject("请完成该评价");
            }
            // 填空题内容校验
            if (typeof value === "string" && item.validateType !== validateEnum.DEFAULT) {
              const fvm = fillValidateMap[item.validateType];
              if (fvm && !fvm.fn(value)) {
                return Promise.reject(fvm.msg);
              }
            }
            // 多选题选项数量校验
            if (Array.isArray(value)) {
              if (item.chooseMin !== 0 && value.length < item.chooseMin) {
                return Promise.reject(`最少选择${item.chooseMin}项`);
              }
              if (item.chooseMax !== 0 && value.length > item.chooseMax) {
                return Promise.reject(`最多选择${item.chooseMax}项`);
              }
            }
            return Promise.resolve();
          },
          trigger: "change"
        }
      ]
    : [];
};
// 矩阵显示
const matrixOptionShow = (type: typeEnum) => {
  return [MATRIX_RADIO, MATRIX_CHECKBOX, MATRIX_SLIDER].includes(type);
};

//判断当前是否为空
const isPageEmpty = (question: questionListType[]) => {
  return question.filter(item => item.isVisible).length === 0;
};

const questionItem = document.getElementsByClassName("question-item"); //获取题目元素

export default function Question({ preview = false }: { preview?: boolean }) {
  const location = useLocation();
  const navigate = useNavigate();
  const [formData] = Form.useForm();
  const [infoHeader, setHeader] = useState({ title: "", content: "", id: "" });
  const [questionData, setQuestionData] = useState<questionListType[][]>([]);
  const [controlData, setControlData] = useState<QuestionControlType[]>([]);
  const [optionLogic, setOptionLogic] = useState<QuestionControlType[]>([]);
  const [startTime, setStartTime] = useState("");
  const [pageIndex, setPageIndex] = useState(0);
  const [answerIdInx, setAnswerIdInx] = useState("");
  useEffect(() => {
    if (location.search) {
      const query = getQueryParams(location.search);
      let surveyId: string = query?.id;
      let answerId: string = query?.answerId;
      if (surveyId) {
        let survey = surveyStore.surveySelected(surveyId);
        if (!survey) {
          return message.error("问卷不存在或问卷已删除");
        } else if (!survey.state && !preview) {
          return message.error("当前问卷已暂停，请稍后重试！");
        }
        setHeader({ title: survey.title, content: survey.content, id: surveyId });
        setPageIndex(0);
        //获取逻辑
        const control = survey.controlLogic.map(item => ({
          id: item.childId,
          parentIds: item.questionIds.split(",").map((item: string) => Number(item)),
          condition: item.condition,
          parentAnswer: item.parentAnswer.split("|").map((item: string) => item.split(",").map(id => Number(id)))
        }));
        setControlData(control);
        const optionLogicList =
          survey.controlOption.map(item => ({
            id: item.childId,
            parentIds: item.questionIds.split(",").map((item: string) => Number(item)),
            condition: item.condition,
            optionId: item.optionId,
            parentAnswer: item.parentAnswer.split("|").map((item: string) => item.split(",").map(id => Number(id)))
          })) || [];
        setOptionLogic(optionLogicList);
        //获取题目列表
        const questionLsit: questionListType[][] = [[]];
        let page = 0;
        survey.question.forEach(item => {
          if (item.isHide !== 1) {
            if (item.type !== PAGING) {
              const show = isQuestionVisible(item.id, control);
              const hideNum = isOptionVisible(item.id, optionLogicList);
              questionLsit[page].push({
                ...item,
                isVisible: show && (hideNum.length === 0 ? true : hideNum.length !== item.option.length),
                hideNum
              });
            } else {
              page++;
              questionLsit.push([]);
            }
          }
        });
        console.log("questionLsit", questionLsit[0]);
        setQuestionData(questionLsit);
        // 判断是否有有答案
        if (answerId) {
          setAnswerIdInx(answerId);
          let answer = answerSelected(surveyId, answerId);
          if (!answer) return message.error("未找到相关答案");
          let state: any = {};
          for (let i in answer.answer) {
            state[answer.answer[i].questionId] = answer.answer[i].content;
          }
          formData.setFieldsValue(state);
        }
        // 获取时间
        setStartTime(getTime());
      } else {
        message.error("没有获取到调查");
      }
    } else {
      message.error("没有获取到调查");
    }
  }, []);
  // 是否显示题目
  const isQuestionVisible = (id: number, control: QuestionControlType[]) => {
    const findControl = control.find(item => item.id === id);
    if (findControl) {
      const form = formData.getFieldsValue();
      let logicList: boolean[] = [];
      findControl.parentIds.forEach((parentId, index) => {
        const answer = findControl.parentAnswer[index];
        logicList.push(
          answer.some(item => {
            return Array.isArray(form[parentId]) ? form[parentId].includes(item) : form[parentId] == item;
          })
        );
      });
      return findControl.condition === "or" ? logicList.some(item => item) : logicList.every(item => item);
    }

    return true;
  };

  // 是否显示选项
  const isOptionVisible = (id: number, logic: QuestionControlType[]) => {
    const filterOption = logic.filter(item => item.id === id);
    const optionShow: number[] = [];
    // 选择控制逻辑处理
    if (filterOption.length) {
      const form = formData.getFieldsValue();
      filterOption.forEach(item => {
        for (const i in item.parentIds) {
          const parentId = item.parentIds[i];
          const answer = item.parentAnswer[i];
          const logicSome = answer.some(item => {
            return Array.isArray(form[parentId]) ? form[parentId].includes(item) : form[parentId] == item;
          });
          if (!logicSome && item.optionId) optionShow.push(item.optionId);
        }
      });
    }
    return optionShow;
  };
  // 更改答案
  const changeAnswer = (id: number) => {
    const childControl = controlData.filter(item => item.parentIds.includes(id));
    const filterOption = optionLogic.filter(item => item.parentIds.includes(id));
    console.log("changeAnswer", formData.getFieldsValue());
    if (childControl.length || filterOption.length) {
      const form = formData.getFieldsValue();
      questionData.forEach(item => {
        item.forEach(item2 => {
          const show = isQuestionVisible(item2.id, childControl);
          const hideNum = isOptionVisible(item2.id, filterOption);
          const optionShow = hideNum.length === 0 || hideNum.length !== item2.option.length;
          if (!show || !optionShow) {
            if (!item2.children || item2.children.length === 0) {
              formData.resetFields([item2.id]);
            } else {
              for (const son of item2.children) {
                formData.resetFields([son.id]);
              }
            }
          } else if (hideNum.length && form[item2.id] !== undefined) {
            let formId = form[item2.id];
            formId = Array.isArray(formId) ? formId.filter(item => !hideNum.includes(item)) : !hideNum.includes(formId) ? form : "";
            formData.setFieldValue(item2.id, formId);
          }
          item2.isVisible = show && optionShow;
          item2.hideNum = hideNum;
        });
      });
      setQuestionData([...questionData]);
    }
  };
  //上一页
  const prevPage = () => {
    if (!answerIdInx)
      questionData[pageIndex].forEach(item => {
        formData.resetFields([item.id]);
      });
    nextPage("prev", pageIndex);
  };

  //分页
  const nextPage = (type: "next" | "prev" = "next", page: number) => {
    page = type === "next" ? page + 1 : page - 1;
    if (isPageEmpty(questionData[page])) {
      nextPage(type, page);
      return;
    }
    setPageIndex(page);
    questionItem[0].scrollIntoView({ behavior: "smooth" });
  };

  //提交数据
  const submitTo = (isSubmit: boolean) => {
    formData
      .validateFields()
      .then(() => {
        if (!isSubmit) return nextPage("next", pageIndex);
        if (preview) {
          message.error("此问卷为预览状态，不能提交！");
          return;
        }
        if (answerIdInx) {
          message.error("此问卷已提交过，不能重复提交！");
          return;
        }
        let answerData: answerType[] = [];
        let form = formData.getFieldsValue(true);
        for (let i in form) {
          answerData.push({ questionId: Number(i), content: form[i] });
        }
        let endTime = getTime();
        let surveyAnswerData: surveyAnswerType = {
          answerId: "answer-" + shortId.generate(),
          surveyId: infoHeader.id,
          surveyTitle: infoHeader.title,
          startTime: startTime,
          endTime: endTime,
          consumTime: timeDiff(startTime, endTime),
          answer: answerData
        };
        answerSave(surveyAnswerData);
        console.log("打印surveyAnswerData", surveyAnswerData);
        navigate("/survey/success", { replace: true });
      })
      .catch(({ errorFields }) => {
        if (errorFields && errorFields.length) {
          //滚动到没有回答的问题
          const firstErrorId: number = errorFields[0].name[0];
          questionItem.namedItem("item-" + firstErrorId)?.scrollIntoView({ behavior: "smooth" });
        }
      });
  };
  return (
    <QuestionContent>
      {infoHeader.title && (
        <header className="question-header">
          <h2 className="header-title">{infoHeader.title}</h2>
        </header>
      )}
      <section className="question-section">
        {infoHeader.content && pageIndex === 0 && <div className="question-content" dangerouslySetInnerHTML={{ __html: infoHeader.content }}></div>}
        <Skeleton active paragraph={{ rows: 16 }} loading={questionData.length === 0}>
          <Form layout="vertical" className="question-list" form={formData}>
            {questionData[pageIndex] &&
              questionData[pageIndex].map(item => (
                <div key={item.id}>
                  {item.isVisible && (
                    <div className="question-item" key={item.id} id={`item-${item.id}`}>
                      {item.type === PARAGRAPH ? (
                        <div dangerouslySetInnerHTML={{ __html: item.title }}></div>
                      ) : matrixOptionShow(item.type) ? (
                        <div className="ant-form-item">
                          <div className="matrix-title">{item.title}</div>
                          <MatrixItrem question={item} rules={rulesValidate(item)}></MatrixItrem>
                        </div>
                      ) : (
                        <Form.Item key={item.id} label={item.title} name={item.id} rules={rulesValidate(item)}>
                          {item.type === RADIO ? (
                            <Radio.Group className="grid" style={generateColumn(item.column)} onChange={() => changeAnswer(item.id)}>
                              {filterAnswer(item.hideNum, item.option).map(subItem => (
                                <Radio key={subItem.id} value={subItem.id}>
                                  {subItem.content}
                                </Radio>
                              ))}
                            </Radio.Group>
                          ) : item.type === CHECKBOX ? (
                            <Checkbox.Group className="grid" style={generateColumn(item.column)} onChange={() => changeAnswer(item.id)}>
                              {filterAnswer(item.hideNum, item.option).map(subItem => (
                                <Checkbox key={subItem.id} value={subItem.id}>
                                  {subItem.content}
                                </Checkbox>
                              ))}
                            </Checkbox.Group>
                          ) : item.type === DROP ? (
                            <Select
                              className="drop-down"
                              placeholder="请选择下拉列表"
                              options={filterAnswer(item.hideNum, item.option)}
                              fieldNames={{ label: "content", value: "id" }}
                              onChange={() => changeAnswer(item.id)}
                            />
                          ) : item.type === SCORE ? (
                            <Rate count={item.option.length} onChange={() => changeAnswer(item.id)} style={{ fontSize: 28 }} />
                          ) : item.type === FILL ? (
                            <>{item.column === 1 ? <Input /> : <TextArea rows={item.column}></TextArea>}</>
                          ) : (
                            item.type === SLIDER && <SliderItem option={item.option}></SliderItem>
                          )}
                        </Form.Item>
                      )}
                    </div>
                  )}
                </div>
              ))}
          </Form>
          {pageIndex !== 0 && (
            <Button block size="large" onClick={prevPage}>
              上一页
            </Button>
          )}
          {pageIndex === questionData.length - 1 ? (
            <Button type="primary" block size="large" onClick={() => submitTo(true)}>
              提交
            </Button>
          ) : (
            <Button type="primary" block size="large" onClick={() => submitTo(false)}>
              下一页
            </Button>
          )}
        </Skeleton>
      </section>
    </QuestionContent>
  );
}
